package com.demo.task.remote.interceptor

import android.util.Log
import com.demo.task.bean.PlanBean
import com.demo.task.bean.Response
import com.demo.task.config.Config.isFirst
import com.demo.task.ext.getExternalFilesDir
import com.google.gson.Gson
import okhttp3.Interceptor
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.ResponseBody.Companion.toResponseBody
import java.io.File


class CacheInterceptor : Interceptor {
    private val gson by lazy { Gson() }
    private val cacheFile: File by lazy {
        File(getExternalFilesDir(), "cache.json").apply {
            if (!this.exists()) {
                createNewFile()
            }
        }
    }

    override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
        val request: Request = chain.request()

        // 检查是否是目标请求
        if (request.url.encodedPath.contains("api/demo/test2")) {
            val response = try {
                chain.proceed(request)
            } catch (e: Exception) {
                Log.e(TAG, "intercept: ", e)
                if (isFirst) {
                    isFirst = false
                    val readCache = readCache() ?: throw e
                    val response = Response(1, listOf(readCache), "", "")
                    val mediaType = "application/json; charset=utf-8".toMediaType()
                    val responseBody = gson.toJson(response).toResponseBody(mediaType)
                    return okhttp3.Response.Builder()
                        .request(request)
                        .protocol(Protocol.HTTP_1_1)
                        .code(200) // No Content
                        .message("OK")
                        .body(responseBody)
                        .build()
                }
                throw e
            }

            val source = response.body!!.source().apply {
                request(Long.MAX_VALUE)
            }
            val responseBody = source.buffer.use {
                it.clone().readUtf8()
            }

            // 解析响应体
            val apiResponse = gson.fromJson(responseBody, Response::class.java)
            val requestData = apiResponse.data

            if (!requestData.isNullOrEmpty()) {
                val json = gson.toJson(requestData[0])
                val data = gson.fromJson(json, PlanBean::class.java)
                val cachedData = readCache()

                if (data.isSamePlan(cachedData?.plan).also { Log.i(TAG, "intercept: $it") }) {
                    //第一次启动，全部都返回
                    if (isFirst) {
                        isFirst = false
                        return response.newBuilder()
                            .code(200) // No Content
                            .message("OK")
                            .body(
                                gson.toJson(apiResponse)
                                    .toResponseBody("application/json; charset=utf-8".toMediaType())
                            )
                            .build()
                    }

                    val planBean = data.apply {
                        cacheFile.writeText(gson.toJson(this))
                        plan = emptyList()
                    }
                    val beanResponse = Response(204, listOf(planBean), null, null)
                    // 如果数据相同，返回空响应
                    return response.newBuilder()
                        .code(200) // No Content
                        .message("OK")
                        .body(gson.toJson(beanResponse).toResponseBody("application/json; charset=utf-8".toMediaType()))
                        .build()
                }

                cacheFile.writeText(json)
            }
            return response

        }

        // 如果不是目标请求，直接返回响应
        return chain.proceed(request)
    }

    private fun readCache(): PlanBean? {
        return runCatching {
            val cacheContent = cacheFile.readText()
            gson.fromJson(cacheContent, PlanBean::class.java)
        }.onFailure { Log.e(TAG, "readCache: ", it) }.getOrNull()
    }

    companion object {
        private const val TAG = "CacheInterceptor"
    }

}